//
// Created by LoveHoneyYou on 2024-11-16.
//
#include "Buffer.h"
#include <csignal>
#include <iostream>
#include <string.h>
#include <sys/socket.h>
#include <sys/uio.h>

Buffer::Buffer(int size)
        :capacity_(size)
{
    data_ = (char*) malloc(size);
    tmpbuf_ = (char*) malloc(4096);
    memset(tmpbuf_,0,size);
    memset(data_,0,size);
}

Buffer::~Buffer()
{
    free(data_);
    free(tmpbuf_);
    data_ = nullptr;
}

int Buffer::Append_Buffer(const char *data, int size)
{
    if(nullptr == data || size <= 0)
    {
        return -1;
    }

    Extend_Room(size);
    memcpy(data_+write_pos_,data,size);
    write_pos_ += size;
    return 0;
}

int Buffer::Append_Buffer(const std::string &data)
{
    int ret = Append_Buffer(data.data());
    return ret;
}

int Buffer::Append_Buffer(const char *data)
{
    int size = strlen(data);
    int ret = Append_Buffer(data,size);
    return ret;
}

int Buffer::Socket_Read(int fd)
{
    struct iovec vec[2];
    int write_enable = Write_Able_Size();
    vec[0].iov_base = data_ + write_pos_;
    vec[0].iov_len = write_enable;

    vec[1].iov_base = tmpbuf_;
    vec[1].iov_len = 4096;
    int res = readv(fd,vec,2);
    if(res == -1)
    {
        return -1;
    }
    else if(res <= write_enable)
    {
        write_pos_ += res;
    }
    else
    {
        write_pos_ = capacity_;
        Append_Buffer(tmpbuf_, res - write_enable);
    }
    free(tmpbuf_);
    std::cout << data_ << std::endl;
    return res;
}

char *Buffer::Find_CRLF()
{
    char* ptr = (char*)memmem(data_ + read_pos_, Read_Able_Size(), "\r\n",2);
    return ptr;
}

int Buffer::Send_Data(int socket)
{
    int read_able = Read_Able_Size();
    if(read_able > 0)
    {
        int count = send(socket,data_+read_pos_,read_able,MSG_NOSIGNAL);
        if(count > 0)
        {
            read_pos_ += count;
            usleep(1);
        }
        return count;
    }
    return 0;
}

void Buffer::Extend_Room(int size)
{
    if(Write_Able_Size() >= size)
    {
        return;
    }
    //合并
    else if(read_pos_ + Write_Able_Size() >= size)
    {
        int read_able = Read_Able_Size();
        memcpy(data_,data_+read_pos_,read_able);
        read_pos_ = 0;
        write_pos_ = read_able;
    }
    //扩容
    else
    {
        void* tmp = realloc(data_,capacity_+size);
        data_  = (char*)tmp;
        capacity_ += size;
    }
}
